package cn.fl.mcr.controller;

import cmm.comm.facade.upload.constant.SysUlFilesRecConstant;
import cmm.mid.core.framework.page.DataResultVO;
import cmm.mid.core.framework.page.ListPageVO;
import cmm.web.core.framework.controller.BaseController;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.mcr.constant.McrApiConstant;
import cn.fl.mcr.service.IMcrLgsUsrService;
import cn.fl.mcr.transform.McrCommCstRecordVOTransform;
import cn.fl.mcr.vo.McrCommCstRecordVO;
import cn.fl.spl.utils.FileUtil;
import cn.fl.system.constant.SysLogConstant;
import cn.fl.system.service.ISysUlFilesRecService;
import cn.lionbridgecapital.loan.model.base.Pager;
import cn.lionbridgecapital.loan.model.condition.McrCommCstRecordQC;
import cn.lionbridgecapital.loan.model.constant.McrCommConstant;
import cn.lionbridgecapital.loan.model.constant.UploadConstant;
import cn.lionbridgecapital.loan.model.dto.McrCommCstRecordDTO;
import cn.lionbridgecapital.loan.service.api.IMcrLgsUsrApiService;
import com.alibaba.fastjson.JSONObject;
import fl.customer.facade.customer.api.ICustomerApiService;
import fl.customer.facade.customer.condition.CstBscInfoQueryCondition;
import fl.customer.facade.customer.dto.CstBscInfoDTO;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author : yangqh521
 * @date : 2019/11/21
 * @desc :
 */
@Controller
@RequestMapping("/mcr/mcrLgsUsr")
public class McrLgsUsrController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(McrCstCrLimSchController.class);

    @Autowired
    IMcrLgsUsrApiService mcrLgsUsrApiService;

    @Autowired
    ISysUlFilesRecService sysUlFilesRecService;

    @Autowired
    ICustomerApiService customerApiService;

    @Autowired
    private IMcrLgsUsrService mcrLgsUsrService;


    /**
     * 日期参数绑定
     * @param binder
     */
    @InitBinder
    public void initBinder(ServletRequestDataBinder binder){
        CustomDateEditor customDateEditor = new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true);
        binder.registerCustomEditor(Date.class, customDateEditor);
    }


    /**
     * 到列表页面
     */
    @RequestMapping("/toListPage.do")
    public ModelAndView toListPage() {
        ModelAndView view = new ModelAndView("/mcr/mcrLgsUsr/mcrLgsUsrList");
        BaseLogUtils.info(logger, "toListPage", "跳转到列表页面.", CurrentThreadContext.getCurrentUserName());
        return view;
    }

    /**
     * 到添加页面
     * 目前只添加外部白名单
     */
    @RequestMapping("/toAddPage.do")
    public ModelAndView toAddPage(Long id) {
        ModelAndView view = new ModelAndView("/mcr/mcrLgsUsr/mcrLgsUsrAdd");
        BaseLogUtils.info(logger, "toAddPage", "跳转到新增页面, [id="+id+"]", CurrentThreadContext.getCurrentUserName());
        view.addObject("id", id);
        return view;
    }

    /**
     * 到修改页面
     *
     */
    @RequestMapping("/toModifyPage.do")
    public ModelAndView toModifyLgsPage(Long id) {
        ModelAndView view = new ModelAndView("/mcr/mcrLgsUsr/mcrLgsUsrModify");
        BaseLogUtils.info(logger, "toModifyPage", "跳转到修改页面, [id="+id+"]", CurrentThreadContext.getCurrentUserName());
        view.addObject("id", id);
        return view;
    }

    /**
     * 到上传客户信息页面
     */
    @RequestMapping(value = "/toMcrCustomerPage.do", method = {RequestMethod.GET})
    public ModelAndView toMcrCustomerPage(HttpServletRequest request, HttpServletResponse response) {
        Long startTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, "toMcrCustomerPage", "加载上传客户数据页面.请求参数：" + this.getRequestParameter(request), CurrentThreadContext.getCurrentUserName());

        ModelAndView view = new ModelAndView("mcr/mcrLgsUsr/mcrImportCustomerPage");

        Long endTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, "toMcrCustomerPage", "加载上传客户数据页面.耗时：" + (endTm - startTm), CurrentThreadContext.getCurrentUserName());
        return view;
    }

    /**
     * 列表数据
     * @param page
     * @param pagesize
     * @return
     */
    @RequestMapping("/initList.do")
    public @ResponseBody ListPageVO initList(@RequestParam(defaultValue = "1") Integer page,
                                             @RequestParam(defaultValue = "10")Integer pagesize,
                                             McrCommCstRecordQC qc) {
        // 查询
        Pager queryPager = new Pager();
        queryPager.setCurrentPage(page);
        queryPager.setEveryPage(pagesize);
        queryPager.setCondition(qc);
        BaseLogUtils.info(logger, "initList", "获取列表, queryPager:" + JSONObject.toJSONString(queryPager),
                CurrentThreadContext.getCurrentUserName());

        // 初始化返回数据
        Integer totalCount = 0;
        List<McrCommCstRecordVO> resultList = new ArrayList();
        try {
            Pager resultPager = mcrLgsUsrApiService.searchMcrCommCstRecordListPage(queryPager);
            BaseLogUtils.info(logger, "initList", "获取列表, resultPager:" + JSONObject.toJSONString(resultPager),
                    CurrentThreadContext.getCurrentUserName());
            // 处理返回数据
            if(resultPager != null && CollectionUtils.isNotEmpty(resultPager.getResultList())){
                totalCount = resultPager.getTotalCount();
                resultList = McrCommCstRecordVOTransform.toVOList((List<McrCommCstRecordDTO>)resultPager.getResultList());
            }
        } catch (Exception e) {
            BaseLogUtils.error(logger, "add", "获取列表异常, queryPager:" + JSONObject.toJSONString(queryPager),
                    CurrentThreadContext.getCurrentUserName(), e);
        }

        // 返回数据
        ListPageVO<McrCommCstRecordVO> listPageVO = new ListPageVO<McrCommCstRecordVO>(resultList, totalCount);
        BaseLogUtils.info(logger, "initList", "获取列表, listPageVO:" + JSONObject.toJSONString(listPageVO),
                CurrentThreadContext.getCurrentUserName());
        return listPageVO;
    }


    /**
     * 新增数据
     * @return
     */
    @RequestMapping("/add.do")
    public @ResponseBody DataResultVO add(McrCommCstRecordVO vo) {

        DataResultVO resultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_DELETE_SUCC);

        BaseLogUtils.info(logger, "add", "添加数据, vo:" + JSONObject.toJSONString(vo),
                CurrentThreadContext.getCurrentUserName());

        McrCommCstRecordDTO dto = McrCommCstRecordVOTransform.toDTO(vo);
        dto.setCrtTm(new Date());
        dto.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
        dto.setBusType(McrCommConstant.MCR_LOAN_TYPE_OUT);
        BaseLogUtils.info(logger, "add", "添加数据, dto:" + JSONObject.toJSONString(dto),
                CurrentThreadContext.getCurrentUserName());

        try {
            mcrLgsUsrApiService.addMcrCommCstRecord(dto);
        } catch (Exception e) {
            BaseLogUtils.error(logger, "add", "添加数据异常, dto:" + JSONObject.toJSONString(dto),
                    CurrentThreadContext.getCurrentUserName(), e);
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("添加数据失败！");
            return resultVO;
        }

        BaseLogUtils.info(logger, "add", "添加数据, resultVO:" + JSONObject.toJSONString(resultVO),
                CurrentThreadContext.getCurrentUserName());

        return resultVO;
    }

    /**
     * 修改数据
     * @return
     */
    @RequestMapping("/modify.do")
    public @ResponseBody DataResultVO modify(McrCommCstRecordVO vo, String fileParams) {

        DataResultVO resultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_OPERATE_SUCC);

        BaseLogUtils.info(logger, "modify", "接收参数, vo:" + JSONObject.toJSONString(vo),
                CurrentThreadContext.getCurrentUserName());

        McrCommCstRecordDTO recordDTO = mcrLgsUsrApiService.selectMcrCommCstRecordById(vo.getId());
        if(recordDTO == null) {
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("不存在对应的白名单信息！");
            return resultVO;
        }

        if(!uploadAttchment(resultVO, vo.getCertNo(), fileParams)){
            BaseLogUtils.info(logger, "modify", "车辆行驶证更新失败！ fileParams:" + fileParams,
                    CurrentThreadContext.getCurrentUserName());
            return resultVO;
        }

        McrCommCstRecordDTO dto = null;
        if(vo.getBusType().equals(McrCommConstant.MCR_LOAN_TYPE_OUT)){
            dto = McrCommCstRecordVOTransform.toDTO(vo);
        }else if (vo.getBusType().equals(McrCommConstant.MCR_LOAN_TYPE_LOGS)){
            dto = new McrCommCstRecordDTO();
            dto.setId(vo.getId());
            dto.setMdfStp(vo.getMdfStp());
        }

        if(dto == null){
            BaseLogUtils.info(logger, "modify", "非外部和物流白名单不允许修改",
                    CurrentThreadContext.getCurrentUserName());
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("非外部和物流白名单不允许修改！");
            return resultVO;
        }

        dto.setMdfTm(new Date());
        dto.setMdfUsrId(CurrentThreadContext.getCurrentUserId());

        BaseLogUtils.info(logger, "modify", "修改数据, dto:" + JSONObject.toJSONString(dto),
                CurrentThreadContext.getCurrentUserName());

        try {
            mcrLgsUsrApiService.modifyMcrCommCstRecord(dto);
        } catch (Exception e) {
            BaseLogUtils.error(logger, "modify", "修改数据异常, dto:" + JSONObject.toJSONString(dto),
                    CurrentThreadContext.getCurrentUserName(), e);
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("修改数据失败！");
            return resultVO;
        }

        BaseLogUtils.info(logger, "modify", "修改数据, resultVO:" + JSONObject.toJSONString(resultVO),
                CurrentThreadContext.getCurrentUserName());

        return resultVO;
    }

    /**
     * 上传车辆行驶证照片
     * @param resultVo
     * @param certNo
     * @param fileParams
     * @return
     */
    private boolean uploadAttchment(DataResultVO resultVo, String certNo, String fileParams){

        if(StringUtils.isBlank(fileParams)){
            BaseLogUtils.info(logger, "uploadAttchment", "未进行上传附件的操作！", CurrentThreadContext.getCurrentUserName());
            return true;
        }
        BaseLogUtils.info(logger, "uploadAttchment", "上传附件! fileParams:" + fileParams, CurrentThreadContext.getCurrentUserName());

        JSONArray fileArray = JSONArray.fromObject(fileParams);
        if(fileArray.size() == 0){
            return true;
        }
        if(fileArray.size() != 2){
            resultVo.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVo.setInfo("车辆行驶证照片需正反两面！");
            return false;
        }

        try {
            CstBscInfoDTO cstBscInfoDTO = this.searchCustomerByCertNo(certNo);
            if(cstBscInfoDTO == null){
                resultVo.setSuccess(BaseConstant.IS_YESNO_NO);
                resultVo.setInfo("未找到对应身份证的客户信息！");
                return false;
            }

            Long cstId = cstBscInfoDTO.getId();
            String cfgOrgCd = UploadConstant.CFG_SYS_USR_ORG_CD;
            String cfgCd = McrApiConstant.MCR_CAR_IMAGE_CFG_CD;
            String tabNm = McrApiConstant.MCR_CAR_IMAGE_TABLE;

            // A正面
            String cfgDtlCd = McrApiConstant.CFG_DTL_MCR_CAR_A;
            String fileA = fileArray.get(0).toString();
            Boolean fileAResult = sysUlFilesRecService.addAttchmntByOne(String.valueOf(cstId), fileA, cfgCd, cfgDtlCd, tabNm, "车辆行驶证正面", null, null, true, cfgOrgCd);

            // B反面
            cfgDtlCd = McrApiConstant.CFG_DTL_MCR_CAR_B;
            String fileB = fileArray.get(1).toString();
            Boolean fileBResult = sysUlFilesRecService.addAttchmntByOne(String.valueOf(cstId), fileB, cfgCd, cfgDtlCd, tabNm, "车辆行驶证反面", null, null, true, cfgOrgCd);

            BaseLogUtils.info(logger, "uploadAttchment", "上传附件结果， fileAResult:" + fileAResult + ", fileBResult:" + fileBResult,
                    CurrentThreadContext.getCurrentUserName());

            if(!fileAResult || !fileBResult){
                resultVo.setSuccess(BaseConstant.IS_YESNO_NO);
                resultVo.setInfo("车辆行驶证照片更新失败！");
                return false;
            }

            BaseLogUtils.info(logger, "uploadAttchment", "上传附件成功！", CurrentThreadContext.getCurrentUserName());

            return true;
        } catch (BaseException e) {
            BaseLogUtils.error(logger, "uploadAttchment", "车辆行驶证更新失败!", e);
            resultVo.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVo.setInfo("车辆行驶证照片更新异常！");
            return false;
        }

    }


    /**
     * 删除功能，不搞
     * @return
     */
    @RequestMapping("/removeById.do")
    public @ResponseBody DataResultVO removeById() {
        DataResultVO resultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_OPERATE_SUCC);
        return resultVO;
    }


    /**
     * 主键获取
     * @return
     */
    @RequestMapping("/getById.do")
    public @ResponseBody DataResultVO getById(Long id) {

        DataResultVO resultVO = new DataResultVO(BaseConstant.IS_YESNO_YES, SysLogConstant.LOG_CMM_OPERATE_SUCC);

        BaseLogUtils.info(logger, "getById", "查询数据, id:" + id, CurrentThreadContext.getCurrentUserName());

        McrCommCstRecordDTO dto = null;
        try {
            dto = mcrLgsUsrApiService.selectMcrCommCstRecordById(id);
        } catch (Exception e) {
            BaseLogUtils.error(logger, "getById", "查询数据, id:" + id,
                    CurrentThreadContext.getCurrentUserName(), e);
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("查询数据失败！");
        }
        if(dto == null){
            resultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            resultVO.setInfo("不存在此条数据！");
        }

        resultVO.setData(McrCommCstRecordVOTransform.toVO(dto));
        BaseLogUtils.info(logger, "getById", "查询数据, resultVO:" + JSONObject.toJSONString(resultVO),
                CurrentThreadContext.getCurrentUserName());

        return resultVO;
    }


    private CstBscInfoDTO searchCustomerByCertNo(String certNo){
        CstBscInfoQueryCondition cstQC = new CstBscInfoQueryCondition();
        cstQC.setCertNo(certNo);
        BaseLogUtils.info(logger, "searchCustomerByCertNo","查询客户，cstQc:{}"+ JSONObject.toJSONString(cstQC));
        List<CstBscInfoDTO> cstBscInfoDTOList = customerApiService.searchCstBscInfoWithCertNo(cstQC);
        BaseLogUtils.info(logger, "searchCustomerByCertNo","查询客户成功，cstBscInfoDTOList:{}" + JSONObject.toJSONString(cstBscInfoDTOList));
        if(CollectionUtils.isNotEmpty(cstBscInfoDTOList)){
            return cstBscInfoDTOList.get(0);
        }
        return null;
    }

    @RequestMapping(value = "/importData.do", method = {RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public DataResultVO importData(HttpServletRequest request, HttpServletResponse response) throws IOException {
        final String methodName = "importData";
        Long startTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, methodName, "excel导入.请求参数：" + this.getRequestParameter(request), CurrentThreadContext.getCurrentUserName());
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "excel导入成功");
        String filePath = request.getParameter("filePath");//文件路径
        ZipOutputStream out = null;
        FileInputStream fis = null;
        try {
            String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
            String realPath = rootPath + filePath;
            DataResultVO resultVO1 = this.mcrLgsUsrService.importData(realPath);
            if (null == resultVO1 || BaseConstant.IS_YESNO_YES != resultVO1.getSuccess()){
                BaseLogUtils.info(logger, methodName, "excel导入失败", CurrentThreadContext.getCurrentUserName());
                result.setSuccess(BaseConstant.IS_YESNO_NO);
                result.setInfo("获取数据失败");
                return result;
            }

            String uuid = UUID.randomUUID().toString().replace("-", "");
            String tmpZipFileName = uuid + ".zip";//临时名称
            out = new ZipOutputStream(response.getOutputStream());
            response.setContentType("application/x-msdownload;");
            response.setHeader("Content-Disposition", "attachment; filename=" + tmpZipFileName);
            request.setCharacterEncoding("UTF-8");

            byte[] buffer = new byte[1024];
            Map<String, Object> rtnMap = (Map<String, Object>) resultVO1.getData();
            //excel 文件路径
            String excelFilePath = (String) rtnMap.get("filePath");
            fis = new FileInputStream(excelFilePath);
            out.putNextEntry(new ZipEntry("小贷客户信息表.xlsx"));
            //下载的文件名写入list
            int bytesRead;
            while (-1 != (bytesRead = fis.read(buffer, 0, buffer.length))) {
                out.write(buffer, 0, bytesRead);
            }
            BaseLogUtils.info(logger, methodName, "上传文件路径：" + realPath);
        } catch (BaseException ex) {
            BaseLogUtils.error(logger, methodName, "excel导入失败", CurrentThreadContext.getCurrentUserName(), ex);
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo(ex.getMessage());
        } catch (Exception e) {
            BaseLogUtils.error(logger, methodName, "excel导入失败.", CurrentThreadContext.getCurrentUserName(), e);
            result.setSuccess(BaseConstant.IS_YESNO_NO);
            result.setInfo("excel导入失败");
        }finally {
            if (null != out) {
                out.flush();
                out.closeEntry();
            }
            if (null != fis) {
                fis.close();
            }
        }
        Long endTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, methodName, "excel导入.耗时：" + (endTm - startTm), CurrentThreadContext.getCurrentUserName());
        BaseLogUtils.info(logger, methodName, "excel导入.返回结果：" + JSONObject.toJSONString(result), CurrentThreadContext.getCurrentUserName());
        return null;
    }

    /**
     * 下载模板
     */
    @RequestMapping(value = "/download.do", method = {RequestMethod.POST})
    @ResponseBody
    public DataResultVO download(HttpServletRequest request, HttpServletResponse response) {
        Long startTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, "download", "下载模板" + this.getRequestParameter(request), CurrentThreadContext.getCurrentUserName());
        DataResultVO vo =new DataResultVO(BaseConstant.IS_YESNO_YES,"模板获取成功");
        String tempPath= FileUtil.getSavePath("template/mcr/mcrCustomerTemplate.xlsx");
        tempPath = tempPath.replace(
                PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH),
                PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH));
        Long endTm = System.currentTimeMillis();
        vo.setData(tempPath);
        BaseLogUtils.info(logger, "download", " 下载模板.耗时：" + (endTm - startTm), CurrentThreadContext.getCurrentUserName());
        BaseLogUtils.info(logger, "download", " 下载模板.返回结果：" + tempPath, CurrentThreadContext.getCurrentUserName());
        return vo;
    }

}
